package com.zmm.util.auth.filter;

import com.zmm.util.auth.enums.ApiType;
import com.zmm.util.auth.model.AuthParam;
import com.zmm.util.auth.registry.annotation.AuthApi;
import org.apache.commons.net.util.SubnetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;

/**
 * @author 900045
 * @description:
 * @name WhiteListFilter
 * @date By 2021-07-06 09:58:19
 */
public class WhiteListFilter implements AuthFilter {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	private ApiType apiType;

	private String  ipWhiteList;

	public WhiteListFilter(ApiType apiType, String ipWhiteList) {
		super();
		this.apiType = apiType;
		this.ipWhiteList = ipWhiteList;
	}


	@Override
	public boolean doFilter(HandlerMethod handler, AuthParam param) {
		if (param == null || apiType == null) {
			return true;
		}
		//校验 是否需要ip白名单校验
		boolean ifCheck = ifCheck(handler, apiType);
		if (!ifCheck) {
			return true;
		}
		param.setCanAnon(ipCheck(ipWhiteList, param.getIpAddress()));
		return param.isCanAnon();
	}


	/**
	 * 接口类型匹配   是否需要ip校验
	 * @author: 900045
	 * @date: 2021-07-06 09:59:23
	 * @throws 
	 * @param method: 
	 * @param apiType: 
	 * @return: boolean
	 **/
	private boolean ifCheck(HandlerMethod method, ApiType apiType) {
		// 1.查看类上是否有加认证类
		AuthApi annotation = method.getBeanType().getAnnotation(AuthApi.class);
		if (annotation == null) {
			annotation = method.getMethodAnnotation(AuthApi.class);
		}
		if (annotation == null) {
			// 不匹配就返回false  
			return false; 
		}
		// 2.比较接口类型
		if (annotation.apiType() == null) {
			// 不匹配就返回false
			return false; 
		}
		return apiType == annotation.apiType();
	}

	/**
	 * ip白名单校验
	 * @author: 900045
	 * @date: 2021-07-06 10:00:49
	 * @throws 
	 * @param whiteList: 
	 * @param ip: 
	 * @return: boolean
	 **/
	protected boolean ipCheck(String whiteList, String ip) {
		logger.info("IP-WHITELIST-CHECK:{} -> {}->", ip, whiteList);
		String[] ips = whiteList.split(",");
		SubnetUtils utils = null;
		for (String ipNet : ips) {
			utils = new SubnetUtils(ipNet);
			utils.setInclusiveHostCount(true);
			if (utils.getInfo().isInRange(ip)) {
				logger.info("IP-WHITELIST-CHECK SUCCESS:{} -> {}", ip, ipNet);
				return true;
			}
		}
		return false;
	}
}
